<script setup lang="ts">
import bignumber, { type BigNumber } from '@peng_kai/kit/libs/bignumber';
import { useElementSize } from '@peng_kai/kit/libs/vueuse';

const props = withDefaults(defineProps<{
  /**
   * 头像
   */
  avatar?: number | string;
  /**
   * 经验
   */
  exp?: [current: BigNumber.Value, total: BigNumber.Value];
  /**
   * 经验百分比
   */
  percent?: number;
  /**
   * 经验条颜色，支持渐变色
   */
  percentColor?: string | [string, string];
  /**
   * 等级
   */
  level?: number | string;
  /**
   * 等级 class
   */
  levelClass?: string;
  /**
   * 等级缩放比例，默认自动计算比例
   */
  levelScale?: number;
}>(), {
  avatar: 1,
  percentColor: () => ['#22C55E', '#22C55E'] as [string, string],
});

const CIRC = 597; // 圆环经验条的周长
const appStore = useAppStore();
const $avatar = ref<HTMLDivElement>();
const { width } = useElementSize($avatar);
const percentColor = computed(() =>
  typeof props.percentColor === 'string'
    ? [props.percentColor, props.percentColor] as [string, string]
    : props.percentColor,
);
const percent = computed(() => {
  const { percent, exp } = props;
  if (typeof percent === 'number') {
    return bignumber(percent).div(100);
  }
  else if (exp?.length === 2) {
    const curr = bignumber(exp[0]);
    const total = bignumber(exp[1]);
    return curr.div(total).dp(2, bignumber.ROUND_DOWN);
  }

  return bignumber(0);
});
const circExp = computed(() => bignumber(CIRC).minus(bignumber(CIRC).times(percent.value)).toNumber());
const avatarSrc = computed(() => {
  const avatar = String(props.avatar);

  if (!Number.isNaN(Number.parseInt(avatar)))
    return appStore.getCdnResPath('avatar', props.avatar);
  else if (avatar.startsWith('http'))
    return avatar;

  return '';
});
const levelScale = computed(() => {
  if (props.levelScale)
    return props.levelScale;

  // 如果没有 levelScale，则自动计算缩放比例
  const scale = width.value / 140;

  return Math.min(Math.max(scale, 0.2), 0.8);
});
</script>

<template>
  <div ref="$avatar" class="relative w-[1.5em]" @pointerenter="$store.user.userInfoQry.refetch()">
    <!-- 辅助左右，使其始终保持正方形 -->
    <div class="pb-full" />

    <!-- 经验条 -->
    <svg
      width="200" height="200" viewBox="0 0 200 200"
      class="absolute left-0 top-0 z-1 h-full w-full scale-120"
    >
      <circle
        cx="100" cy="100" r="95" fill="none" stroke="url(#gradient)" stroke-width="10"
        :stroke-dasharray="CIRC" :stroke-dashoffset="circExp" stroke-linecap="round"
        transform="rotate(-90 100 100)"
      />
      <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0" :stop-color="percentColor[0]" />
        <stop offset="0.5" :stop-color="percentColor[1]" />
      </linearGradient>
    </svg>

    <!-- 头像 -->
    <img
      class="avatar-img absolute left-0 top-0 h-full w-full rounded-full bg-white/10"
      :src="avatarSrc"
    >

    <!-- 等级 -->
    <div v-if="level" class="level border-6 border-[#111923] border-solid bg-[#dc2626] text-white" :class="props.levelClass">
      {{ props.level }}
    </div>
  </div>
</template>

<style lang="scss" scoped>
.avatar-img[src=''] {
  opacity: 0;
}

.level {
  --_level-scale: v-bind('levelScale');

  position: absolute;
  box-sizing: content-box;
  bottom: 0;
  left: 50%;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 3.5ch;
  line-height: 1.4;
  border-radius: 999px;
  text-align: center;
  font-size: 40px;
  transform: translate(-50%, 50%) scale(var(--_level-scale));
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
</style>
